/*****************************************************************************/
/*                                                                           */
/*    Domino Operation System Driver Module                                  */
/*                                                                           */
/*    Copyright (C) 2013 Laszlo Arvai                                        */
/*                                                                           */
/*    ------------------------------------------------------------------     */
/*    Analog Devices AD779x ADC driver                                       */
/*****************************************************************************/

#ifndef __drvAD779x_h
#define __drvAD779x_h

///////////////////////////////////////////////////////////////////////////////
// Includes
#include <krnlTypes.h>

///////////////////////////////////////////////////////////////////////////////
// Constants

/* Registers */
#define AD779x_REG_COMM         0 /* Communications Register (WO, 8-bit) */
#define AD779x_REG_STAT         0 /* Status Register         (RO, 8-bit) */
#define AD779x_REG_MODE         1 /* Mode Register           (RW, 16-bit */
#define AD779x_REG_CONF         2 /* Configuration Register  (RW, 16-bit) */
#define AD779x_REG_DATA         3 /* Data Register           (RO, 16-/24-bit) */
#define AD779x_REG_ID           4 /* ID Register             (RO, 8-bit) */
#define AD779x_REG_IO           5 /* IO Register             (RO, 8-bit) */
#define AD779x_REG_OFFSET       6 /* Offset Register         (RW, 16-bit (RW, 16-bit (AD7792)/24-bit (AD7793)) */
#define AD779x_REG_FULLSALE     7 /* Full-Scale Register     (RW, 16-bit (AD7792)/24-bit (AD7793)) */

/* Communications Register Bit Designations (AD779x_REG_COMM) */
#define AD779x_COMM_WDIS        (1 << 7) /* Write Disable */
#define AD779x_COMM_WEN         (0 << 7) /* Write Enable */
#define AD779x_COMM_WRITE       (0 << 6) /* Write Operation */
#define AD779x_COMM_READ        (1 << 6) /* Read Operation */
#define AD779x_COMM_ADDR(x)     (((x) & 0x7) << 3) /* Register Address */
#define AD779x_COMM_CREAD       (1 << 2) /* Continuous Read of Data Register */

/* Status Register Bit Designations (AD779x_REG_STAT) */
#define AD779x_STAT_RDY         (1 << 7) /* Ready */
#define AD779x_STAT_ERR         (1 << 6) /* Error (Overrange, Underrange) */
#define AD779x_STAT_CH3         (1 << 2) /* Channel 3 */
#define AD779x_STAT_CH2         (1 << 1) /* Channel 2 */
#define AD779x_STAT_CH1         (1 << 0) /* Channel 1 */

/* Mode Register Bit Designations (AD779x_REG_MODE) */
#define AD779x_MODE_FS0       0
#define AD779x_MODE_FS1       1
#define AD779x_MODE_FS2       2
#define AD779x_MODE_FS3       3
#define AD779x_MODE_CLK0      6
#define AD779x_MODE_CLK1      7
#define AD779x_MODE_PSW				12
#define AD779x_MODE_MD0       13
#define AD779x_MODE_MD1       14
#define AD779x_MODE_MD2       15

#define AD779x_MODE_CONTINOUS           (0<<AD779x_MODE_MD2) | (0<<AD779x_MODE_MD1) | (0<<AD779x_MODE_MD0) /* Continuous Conversion Mode */
#define AD779x_MODE_SINGLE              (0<<AD779x_MODE_MD2) | (0<<AD779x_MODE_MD1) | (1<<AD779x_MODE_MD0) /* Single Conversion Mode */
#define AD779x_MODE_IDLE                (0<<AD779x_MODE_MD2) | (1<<AD779x_MODE_MD1) | (0<<AD779x_MODE_MD0) /* Idle Mode */
#define AD779x_MODE_POWERDOWN           (0<<AD779x_MODE_MD2) | (1<<AD779x_MODE_MD1) | (1<<AD779x_MODE_MD0) /* Power-Down Mode */
#define AD779x_MODE_INTERNAL_ZSC        (1<<AD779x_MODE_MD2) | (0<<AD779x_MODE_MD1) | (0<<AD779x_MODE_MD0) /* Internal Zero-Scale Calibration */
#define AD779x_MODE_INTERNAL_FSC        (1<<AD779x_MODE_MD2) | (0<<AD779x_MODE_MD1) | (1<<AD779x_MODE_MD0) /* Internal Full-Scale Calibration */
#define AD779x_MODE_SYSTEM_ZSC          (1<<AD779x_MODE_MD2) | (1<<AD779x_MODE_MD1) | (0<<AD779x_MODE_MD0) /* System Zero-Scale Calibration */
#define AD779x_MODE_SYSTEM_FSC          (1<<AD779x_MODE_MD2) | (1<<AD779x_MODE_MD1) | (1<<AD779x_MODE_MD0) /* System Full-Scale Calibration */

#define AD779x_MODE_CLK_INTERNAL64_NOOUT   (0<<AD779x_MODE_CLK1) | (0<<AD779x_MODE_CLK0) /* Internal 64 kHz Clock not available at the CLK pin */
#define AD779x_MODE_CLK_INTERNAL64_OUT     (0<<AD779x_MODE_CLK1) | (1<<AD779x_MODE_CLK0) /* Internal 64 kHz Clock available at the CLK pin */
#define AD779x_MODE_CLK_EXTERNAL64         (1<<AD779x_MODE_CLK1) | (0<<AD779x_MODE_CLK0) /* External 64 kHz Clock */
#define AD779x_MODE_CLK_EXTERNAL64_DIV2    (1<<AD779x_MODE_CLK1) | (1<<AD779x_MODE_CLK0) /* External Clock divided by 2 */

#define AD779x_MODE_AMP_REDUCE_COMMON	  (1<<9)
#define AD779x_MODE_CHOP_DISABLE				(1<<4)


/* Update rates */
#define AD779x_MODE_RATE_0Hz               (0<<AD779x_MODE_FS3) | (0<<AD779x_MODE_FS2) | (0<<AD779x_MODE_FS1) | (0<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_470Hz             (0<<AD779x_MODE_FS3) | (0<<AD779x_MODE_FS2) | (0<<AD779x_MODE_FS1) | (1<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_242Hz             (0<<AD779x_MODE_FS3) | (0<<AD779x_MODE_FS2) | (1<<AD779x_MODE_FS1) | (0<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_123Hz             (0<<AD779x_MODE_FS3) | (0<<AD779x_MODE_FS2) | (1<<AD779x_MODE_FS1) | (1<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_62Hz              (0<<AD779x_MODE_FS3) | (1<<AD779x_MODE_FS2) | (0<<AD779x_MODE_FS1) | (0<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_50Hz              (0<<AD779x_MODE_FS3) | (1<<AD779x_MODE_FS2) | (0<<AD779x_MODE_FS1) | (1<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_39Hz              (0<<AD779x_MODE_FS3) | (1<<AD779x_MODE_FS2) | (1<<AD779x_MODE_FS1) | (0<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_33Hz              (0<<AD779x_MODE_FS3) | (1<<AD779x_MODE_FS2) | (1<<AD779x_MODE_FS1) | (1<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_19Hz              (1<<AD779x_MODE_FS3) | (0<<AD779x_MODE_FS2) | (0<<AD779x_MODE_FS1) | (0<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_16Hz              (1<<AD779x_MODE_FS3) | (0<<AD779x_MODE_FS2) | (0<<AD779x_MODE_FS1) | (1<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_16Hz_2            (1<<AD779x_MODE_FS3) | (0<<AD779x_MODE_FS2) | (1<<AD779x_MODE_FS1) | (0<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_12Hz              (1<<AD779x_MODE_FS3) | (0<<AD779x_MODE_FS2) | (1<<AD779x_MODE_FS1) | (1<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_10Hz              (1<<AD779x_MODE_FS3) | (1<<AD779x_MODE_FS2) | (0<<AD779x_MODE_FS1) | (0<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_8Hz               (1<<AD779x_MODE_FS3) | (1<<AD779x_MODE_FS2) | (0<<AD779x_MODE_FS1) | (1<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_6Hz               (1<<AD779x_MODE_FS3) | (1<<AD779x_MODE_FS2) | (1<<AD779x_MODE_FS1) | (0<<AD779x_MODE_FS0)
#define AD779x_MODE_RATE_4Hz               (1<<AD779x_MODE_FS3) | (1<<AD779x_MODE_FS2) | (1<<AD779x_MODE_FS1) | (1<<AD779x_MODE_FS0)

/* configuration register bits */
#define AD779x_CONF_CH0       0
#define AD779x_CONF_CH1       1
#define AD779x_CONF_CH2       2
#define AD779x_CONF_CH3	      3
#define AD779x_CONF_BUF       4
#define AD779x_CONF_REFDET		5
#define AD779x_CONF_REFSEL0   6
#define AD779x_CONF_REFSEL1   7
#define AD779x_CONF_G0        8
#define AD779x_CONF_G1        9
#define AD779x_CONF_G2        10
#define AD779x_CONF_BOOST     11
#define AD779x_CONF_UB        12
#define AD779x_CONF_BO        13
#define AD779x_CONF_VBIAS0    14
#define AD779x_CONF_VBIAS1    15

#define AD779x_CONF_BIAS_DISABLE     (0<<AD779x_CONF_VBIAS1) | (0<<AD779x_CONF_VBIAS0) /* Bias voltage generator disabled  */
#define AD779x_CONF_BIAS_AIN1        (0<<AD779x_CONF_VBIAS1) | (1<<AD779x_CONF_VBIAS0) /* Bias voltage generator connected to AIN1(?) */
#define AD779x_CONF_BIAS_AIN2        (1<<AD779x_CONF_VBIAS1) | (0<<AD779x_CONF_VBIAS0) /* Bias voltage generator connected to AIN2(?) */
#define AD779x_CONF_BIAS_AIN3				 (1<<AD779x_CONF_VBIAS1) | (1<<AD779x_CONF_VBIAS0) /* Bias voltage generator connected to AIN3(?) */

#define AD779x_CONF_BURNOUT_ENABLE   (1<<AD779x_CONF_BO)		/* Burnout Current Enable */
#define AD779x_CONF_SET_UNIPOLAR     (1<<AD779x_CONF_UB)		/* Unipolar Enable */
#define AD779x_CONF_BIAS_INCREASE    (1<<AD779x_CONF_BOOST)	/* Boost Enable */

// Gain settings
#define AD779x_CONF_GAIN_1            (0<<AD779x_CONF_G2) | (0<<AD779x_CONF_G1) | (0<<AD779x_CONF_G0)
#define AD779x_CONF_GAIN_2            (0<<AD779x_CONF_G2) | (0<<AD779x_CONF_G1) | (1<<AD779x_CONF_G0)
#define AD779x_CONF_GAIN_4            (0<<AD779x_CONF_G2) | (1<<AD779x_CONF_G1) | (0<<AD779x_CONF_G0)
#define AD779x_CONF_GAIN_8            (0<<AD779x_CONF_G2) | (1<<AD779x_CONF_G1) | (1<<AD779x_CONF_G0)
#define AD779x_CONF_GAIN_16           (1<<AD779x_CONF_G2) | (0<<AD779x_CONF_G1) | (0<<AD779x_CONF_G0)
#define AD779x_CONF_GAIN_32           (1<<AD779x_CONF_G2) | (0<<AD779x_CONF_G1) | (1<<AD779x_CONF_G0)
#define AD779x_CONF_GAIN_64           (1<<AD779x_CONF_G2) | (1<<AD779x_CONF_G1) | (0<<AD779x_CONF_G0)
#define AD779x_CONF_GAIN_128          (1<<AD779x_CONF_G2) | (1<<AD779x_CONF_G1) | (1<<AD779x_CONF_G0)

#define AD779x_CONF_REF_EXT_REFIN1P_REFIN1N		(0<<AD779x_CONF_REFSEL1) |	(0<<AD779x_CONF_REFSEL0) /* External reference applied between REFIN1(+) and REFIN1(?) */
#define AD779x_CONF_REF_EXT_REFIN2P_REFIN2N		(0<<AD779x_CONF_REFSEL1) |	(1<<AD779x_CONF_REFSEL0) /* External reference applied between REFIN2(+) and REFIN2(?) */
#define AD779x_CONF_REF_INTERNAL							(1<<AD779x_CONF_REFSEL1) |	(0<<AD779x_CONF_REFSEL0)  /* Internal 1.17 V reference */

#define AD779x_CONF_BUFFER_ENABLE     (1<<AD779x_CONF_BUF) /* Buffered Mode Enable */

#define AD779x_CONF_CH_AIN1P_AIN1M    (0<<AD779x_CONF_CH3) | (0<<AD779x_CONF_CH2) | (0<<AD779x_CONF_CH1) | (0<<AD779x_CONF_CH0) /* AIN1(+) - AIN1(-) */
#define AD779x_CONF_CH_AIN2P_AIN2M    (0<<AD779x_CONF_CH3) | (0<<AD779x_CONF_CH2) | (0<<AD779x_CONF_CH1) | (1<<AD779x_CONF_CH0) /* AIN2(+) - AIN2(-) */
#define AD779x_CONF_CH_AIN3P_AIN3M    (0<<AD779x_CONF_CH3) | (0<<AD779x_CONF_CH2) | (1<<AD779x_CONF_CH1) | (0<<AD779x_CONF_CH0) /* AIN3(+) - AIN3(-) */
#define AD779x_CONF_CH_AIN4P_AIN4M    (0<<AD779x_CONF_CH3) | (0<<AD779x_CONF_CH2) | (1<<AD779x_CONF_CH1) | (1<<AD779x_CONF_CH0) /* AIN4(+) - AIN4(-) */
#define AD779x_CONF_CH_AIN5P_AIN5M    (0<<AD779x_CONF_CH3) | (1<<AD779x_CONF_CH2) | (0<<AD779x_CONF_CH1) | (0<<AD779x_CONF_CH0) /* AIN5(+) - AIN5(-) */
#define AD779x_CONF_CH_AIN6P_AIN6M    (0<<AD779x_CONF_CH3) | (1<<AD779x_CONF_CH2) | (0<<AD779x_CONF_CH1) | (1<<AD779x_CONF_CH0) /* AIN6(+) - AIN6(-) */
#define AD779x_CONF_CH_TEMP           (0<<AD779x_CONF_CH3) | (1<<AD779x_CONF_CH2) | (1<<AD779x_CONF_CH1) | (0<<AD779x_CONF_CH0) /* Temp Sensor */
#define AD779x_CONF_CH_AVDD_MONITOR   (0<<AD779x_CONF_CH3) | (1<<AD779x_CONF_CH2) | (1<<AD779x_CONF_CH1) | (1<<AD779x_CONF_CH0) /* AVDD Monitor */
#define AD779x_CONF_CH_AIN1M_AIN1M    (1<<AD779x_CONF_CH3) | (0<<AD779x_CONF_CH2) | (0<<AD779x_CONF_CH1) | (0<<AD779x_CONF_CH0) /* AIN1(-) - AIN1(-) */

// IO register bits
#define AD779x_IO_IEXCEN0   0
#define AD779x_IO_IEXCEN1   1
#define AD779x_IO_IEXCDIR0  2
#define AD779x_IO_IEXCDIR1  3

/* IO (Excitation Current Sources) Register Bit Designations (AD779x_REG_IO) */
#define AD779x_IO_DIR_11_22          (0<<IEXCDIR1) | (0<<IEXCDIR0) /* IEXC1 connect to IOUT1, IEXC2 connect to IOUT2 */
#define AD779x_IO_DIR_12_21          (0<<IEXCDIR1) | (1<<IEXCDIR0) /* IEXC1 connect to IOUT2, IEXC2 connect to IOUT1 */
#define AD779x_IO_DIR_1              (1<<IEXCDIR1) | (0<<IEXCDIR0) /* Both current sources IEXC1,2 connect to IOUT1 */
#define AD779x_IO_DIR_2              (1<<IEXCDIR1) | (1<<IEXCDIR0) /* Both current sources IEXC1,2 connect to IOUT2 */

#define AD779x_IO_SOURCE_DISABLE     (0<<IEXCEN1) | (0<<IEXCEN0) /* Excitation Current Disabled */
#define AD779x_IO_SOURCE_10uA        (0<<IEXCEN1) | (1<<IEXCEN0) /* Excitation Current 10uA */
#define AD779x_IO_SOURCE_210uA       (1<<IEXCEN1) | (0<<IEXCEN0) /* Excitation Current 210uA */
#define AD779x_IO_SOURCE_1mA         (1<<IEXCEN1) | (1<<IEXCEN0) /* Excitation Current 1mA */

/* ID Register Bit Designations (AD779x_REG_ID) */
#define AD7785_ID               0xB
#define AD7792_ID               0xA
#define AD779x_ID               0xB
#define AD7794_ID               0xF
#define AD7795_ID               0xF
#define AD7796_ID               0xA
#define AD7797_ID               0xB
#define AD7798_ID               0x8
#define AD7799_ID               0x9
#define AD779x_ID_MASK          0xF


///////////////////////////////////////////////////////////////////////////////
// Function prototypes
void drvAD779xInit(void);
void drvAD779xReset(void);
void drvAD779xSetModeRegister(dosWord in_mode);
void drvAD779xSetConfigRegister(dosWord in_mode);
void drvAD779xAsyncStartDataRead(void);
dosBool drvAD779xAsyncIsDataAvailable(void);
void drvAD779xAsyncStopDataRead(void);
dosDWord drvAD779xAsyncReadDataAndStop(void);

#endif
